#include "../Utils.h"

using namespace yhaida;
//*****************************namespace CurrentThread*****************************
//声明
__thread pid_t CurrentThread::currend_tid = 0;
__thread const char *CurrentThread::currend_thread_name = "unnamedTthread";

pid_t CurrentThread::tid()
{
  if (currend_tid == 0)
  {
    currend_tid = static_cast<pid_t>(syscall(SYS_gettid)); // syscall定义在<unistd.h>中的
  }
  return currend_tid;
}
const char *CurrentThread::name()
{
  return currend_thread_name;
}
// getpid()得到的是进程的pid，在内核中，每个线程都有自己的PID，要得到线程的PID,必须用syscall(SYS_gettid);
//注意：在main函数中,getpid()进程号就是syscall(SYS_gettid)线程ID.在pthread_create子线程里就不是进程的PID了.
bool CurrentThread::isMainThread()
{
  return tid() == getpid();
}

//*****************************namespace Detail::FixedBuffer*****************************
template <int SIZE>
const char *Detail::FixedBuffer<SIZE>::debugString()
{
  *_cur = '\0';
  return _data;
}

template <int SIZE>
void Detail::FixedBuffer<SIZE>::cookieStart()
{
}

template <int SIZE>
void Detail::FixedBuffer<SIZE>::cookieEnd()
{
}

//模板特化
template class Detail::FixedBuffer<Detail::kSmallBuffer>;
template class Detail::FixedBuffer<Detail::kLargeBuffer>;
//*****************************namespace Detail::File*****************************
Detail::File::File(const std::string &filename)
    : _fp(fopen(filename.data(), "ae")),
      _writtenBytes(0)
{
  //流文件 关联 缓存
  // std::cout<<"filename.data()"<<filename.data()<<std::endl;
  setbuffer(_fp, _buff, sizeof(_buff));
}

Detail::File::~File()
{
  if (_fp)
  {
    fclose(_fp);
  }
}

void Detail::File::append(const char *str, const size_t length)
{
  //一次写不完
  int n = write(str, length);
  size_t remain = length - n;
  while (remain > 0)
  {
    int bt = write(str + n, remain);
    if (bt == 0)
    {
      // bt==0时候就是fwrite_unlock遇到错误了，调用ferror可以将错误码展示出来。
      int error = ferror(_fp);
      if (error)
      {
        char errorBuff[128];
        fprintf(stderr, "LogFile::File::append() failed %s\n", errorBuff);
        break;
      }
    }
    remain -= bt;
  }
  _writtenBytes += length;
}

void Detail::File::flush()
{
  fflush(_fp);
}

const size_t Detail::File::getWriteBytes() const
{
  return _writtenBytes;
}

size_t Detail::File::write(const char *str, size_t length)
{
  // #undef fwrite_unlocked
  return fwrite_unlocked(str, 1, length, _fp);
}
